﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SolrNet;
using NCT.Framework;
using System.Net;
using System.Xml;

namespace VISS.API.Users {
    class SorlUserProfileIdx : IUserIdx {

        private static ISolrOperations<SolrUserIdxEnt> solr = null;

        #region IUserProfileIdx Members

        public bool Add(UserGeneralProfileEnt gItem) {
            try {
                SolrUserIdxEnt item = SolrUserIdxEnt.FromUserGeneralProfileEnt(gItem);
                solr.Add(item);
                Commit();
                return true;
            }
            catch {
            }
            return false;
        }

        public bool Add(List<UserGeneralProfileEnt> gItems) {
            try {
                List<SolrUserIdxEnt> items = new List<SolrUserIdxEnt>();
                for (int i = 0; i < gItems.Count; i++) {
                    items.Add(SolrUserIdxEnt.FromUserGeneralProfileEnt(gItems[i]));
                }
                solr.Add(items);
                Commit();
                return true;
            }
            catch {
            }
            return false;
        }

        public bool Update(UserGeneralProfileEnt gItem) {
            return Add(gItem);
        }

        public bool Update(List<UserGeneralProfileEnt> gItems) {
            return Add(gItems);
        }

        public bool Delete(string userKey) {
            try {
                solr.Delete(new SolrQuery("UserKey:" + userKey));
                Commit();
                return true;
            }
            catch { }
            return false;
        }

        public bool DeleteAll() {
            try {
                solr.Delete(new SolrQuery("UserKey:[* TO *]"));
                Commit();
                return true;
            }
            catch { }
            return false;
        }

        public List<SolrUserIdxEnt> QuickSearch(int pageIndex, int pageSize, UserSrhEnt srhItem, bool forceRefresh, out int totalRecords) {
            string query = ParseToQuery(pageIndex, pageSize, srhItem, forceRefresh);

            List<SolrUserIdxEnt> result = new List<SolrUserIdxEnt>();
            totalRecords = 0;

            string url = ConfigInfo.SOLRINDEXING_UserProfile_URL;
            if (!url.EndsWith("/")) {
                url += "/";
            }
            url += query;

            WebClient client = new WebClient();
            client.Encoding = new UTF8Encoding();
            string response = client.DownloadString(url);
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(response);
            XmlNodeList resultLs = xml.GetElementsByTagName("result");
            if (resultLs.Count > 0) {
                totalRecords = ConvertUtils.ToInt(resultLs[0].Attributes["numFound"].Value);
                XmlNodeList docLs = resultLs[0].SelectNodes("doc");
                for (int j = 0; j < docLs.Count; ++j) {
                    //result.Add(CreateSongEntFromXmlNode(docLs[j]));
                }
            }
            return result;
        }

        #endregion

        #region Private Methods

        private bool Commit() {
            try {
                solr.Commit();
                solr.Optimize();
                return true;
            }
            catch { }
            return false;
        }

        /// <summary>
        /// Now only use for quick search
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="srhItem">search condition</param>
        /// <param name="forceRefresh">Not use now</param>
        /// <returns>query string for quick search</returns>
        private string ParseToQuery(int pageIndex, int pageSize, UserSrhEnt srhItem, bool forceRefresh) {
            string template = "select?q={0}&start={1}&rows={2}";

            string strTemplateQuery = " AND {0}:({1})";
            //Not use now
            string strTemplateSort = "&sort={0} {1}";

            string strQuery = "";

            if (srhItem.CityID > 0) {
                strQuery += string.Format(strTemplateQuery, "CityID", srhItem.CityID);
            }

            if (srhItem.CountryID > 0) {
                strQuery += string.Format(strTemplateQuery, "CountryID", srhItem.CountryID);
            }

            if (srhItem.EducationID > 0) {
                strQuery += string.Format(strTemplateQuery, "EducationID", srhItem.EducationID);
            }

            if (srhItem.FromBirthDate > DateTimeUtils.MinValue) {
                strQuery += string.Format(strTemplateQuery, "FromBirthDate", srhItem.FromBirthDate);
            }

            if (srhItem.ToBirthDate > DateTimeUtils.MinValue) {
                strQuery += string.Format(strTemplateQuery, "ToBirthDate", srhItem.ToBirthDate);
            }

            if (srhItem.Gender != EUserGender.Unknown) {
                strQuery += string.Format(strTemplateQuery, "Gender", srhItem.Gender);
            }

            int rowStart = (pageIndex - 1) * pageSize;
            strQuery = string.Format(template, strQuery, rowStart, pageSize);

            return strQuery;
        }

        /*
        private SongEnt CreateSongEntFromXmlNode(XmlNode node) {
            SongEnt item = new SongEnt();
            for (int
                i = 0; i < node.ChildNodes.Count; ++i) {
                XmlNode ch = node.ChildNodes[i];
                switch (ch.Attributes["name"].Value) {
                    case "Added":
                        item.Added = ConvertUtils.ToInt(ch.InnerText); break;
                    case "DateCreated":
                        item.DateCreated = Convert.ToDateTime(ch.InnerText); break;
                    case "DateModified":
                        item.DateModified = Convert.ToDateTime(ch.InnerText); break;
                    case "Downloaded":
                        item.Downloaded = ConvertUtils.ToInt(ch.InnerText); break;
                    case "FileName":
                        item.FileName = ConvertUtils.ToString(ch.InnerText); break;
                    case "GenreID":
                        item.GenreID = ConvertUtils.ToInt(ch.InnerText); break;
                    case "GenreKey":
                        item.GenreKey = ConvertUtils.ToString(ch.InnerText); break;
                    case "GenreName":
                        item.GenreName = ConvertUtils.ToString(ch.InnerText); break;
                    case "HasLyric":
                        item.HasLyric = ConvertUtils.ToBool(ch.InnerText); break;
                    case "KBit":
                        item.KBit = ConvertUtils.ToInt(ch.InnerText); break;
                    case "SingerIDs":
                        item.SingerIDs = ConvertUtils.ToString(ch.InnerText); break;
                    case "SingerNames":
                        item.SingerNames = ConvertUtils.ToString(ch.InnerText); break;
                    case "SongID":
                        item.SongID = ConvertUtils.ToInt(ch.InnerText); break;
                    case "SongKey":
                        item.SongKey = ConvertUtils.ToString(ch.InnerText); break;
                    case "SongTitle":
                        item.SongTitle = ConvertUtils.ToString(ch.InnerText); break;
                    case "Status":
                        item.Status = (SongStatus)Enum.Parse(typeof(SongStatus), ch.InnerText); break;
                    case "StoreID":
                        item.StoreID = ConvertUtils.ToInt(ch.InnerText); break;
                    case "Tags":
                        item.Tags = ConvertUtils.ToString(ch.InnerText); break;
                    case "Type":
                        item.Type = (SongType)Enum.Parse(typeof(SongType), ch.InnerText); break;
                    case "UserCreated":
                        item.UserCreated = ConvertUtils.ToString(ch.InnerText); break;
                    case "UserModified":
                        item.UserModified = ConvertUtils.ToString(ch.InnerText); break;
                }
            }
            return item;
        }
        */

        #endregion
    }
}
